package com.jetgege.smartbox.Tools;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;

import com.jetgege.smartbox.Base.App;

import java.util.UUID;

/**
 * Created by JJT-ssd on 2017/3/27.
 */

public class BluetoothHelper {

    private static final int SCAN_PERIOD=8000;

    public static BluetoothGatt mBluetoothGatt;
    public static BluetoothGattService mBluetoothGattService;
    public static BluetoothGattCharacteristic mCharacteristic;
    private static CharacteristicCallBack dataCallBack;

    private static String serviceUUID = "0000FFF0-0000-1000-8000-00805F9B34FB";
    private static String characteristicUUID = "0000FFF1-0000-1000-8000-00805F9B34FB";
    private static String descriptorUUID ="00002902-0000-1000-8000-00805f9b34fb";


    public static final String ACTION_BLE_DISCOVERY_STARTED = "com.goockr.BLE_DISCOVERY_STARTED";
    public static final String ACTION_BLE_DISCOVERY_FINISHED = "com.goockr.BLE_DISCOVERY_FINISHED";
    public static final String ACTION_BLE_CONNECTED = "com.goockr.BLE_CONNECTED";
    public static final String ACTION_BLE_DISCONNECTED = "com.goockr.BLE_DISCONNECTED";

    private static Thread sendThread;
    private static boolean isConnected=false;
    public static boolean isConnected() {return isConnected;}
    public static void setConnected(boolean connected) {isConnected = connected;}

    /**
     * 注册蓝牙通知
     */
    public static void registerBluetoothBroadcast(Context mContext,BroadcastReceiver mReceiver) {

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothHelper.ACTION_BLE_DISCOVERY_FINISHED);
        filter.addAction(BluetoothHelper.ACTION_BLE_DISCOVERY_STARTED);
        filter.addAction(BluetoothHelper.ACTION_BLE_CONNECTED);
        filter.addAction(BluetoothHelper.ACTION_BLE_DISCONNECTED);
        mContext.registerReceiver(mReceiver, filter);
    }

    /**
     * 注销蓝牙通知
     * @param mContext
     * @param mReceiver
     */
    public static void unRegisterBluetoothBroadcast(Context mContext,BroadcastReceiver mReceiver) {
        mContext.unregisterReceiver(mReceiver);
    }

    public static int openDevice()
    {
        if (BluetoothAdapter.getDefaultAdapter() == null) {

            return -1;//设备不支持蓝牙功能
        }
        if (!BluetoothAdapter.getDefaultAdapter().isEnabled())
        {
            BluetoothAdapter.getDefaultAdapter().enable();
            return 1;
        }
        return 0;
    }

    public static boolean closeDevice()
    {
        if (BluetoothAdapter.getDefaultAdapter().isEnabled())
        {
            BluetoothAdapter.getDefaultAdapter().disable();
            return true;
        }else return false;
    }

    public static void  cancle()
    {
        if (mBluetoothGatt == null) return;
        mBluetoothGatt.disconnect();
        setConnected(false);
        mBluetoothGatt.close();
        mCharacteristic=null;
        mBluetoothGattService=null;
        mBluetoothGatt = null;
        dataCallBack=null;

        broadcastUpdate(ACTION_BLE_DISCONNECTED);
    }

    public static boolean isScaning=false;
    public static void scanLeDevice(final BluetoothAdapter.LeScanCallback mLeScanCallback) {
        openDevice();
        if (!isScaning)
        {
            broadcastUpdate(ACTION_BLE_DISCOVERY_STARTED);
            BluetoothAdapter.getDefaultAdapter().startLeScan(mLeScanCallback);
            isScaning=true;
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    stopScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);
        }else {
            stopScan(mLeScanCallback);
        }
    }

    public static void stopScan(final BluetoothAdapter.LeScanCallback mLeScanCallback)
    {
        if (isScaning){
            broadcastUpdate(ACTION_BLE_DISCOVERY_FINISHED);
            BluetoothAdapter.getDefaultAdapter().stopLeScan(mLeScanCallback);
            isScaning=false;
        }
    }

    public static void conn(final BluetoothDevice device, CharacteristicCallBack characteristicCallBack)
    {
        dataCallBack=characteristicCallBack;
        //连接操作为耗时操作，需要开线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                mBluetoothGatt=device.connectGatt(App.mContext, false,mGattCallback);
            }
        }).start();
    }

    private static final BluetoothGattCallback mGattCallback =new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

            if (newState == BluetoothProfile.STATE_CONNECTED) {
                mBluetoothGatt.discoverServices();//搜索服务
            }else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                setConnected(false);
                broadcastUpdate(ACTION_BLE_DISCONNECTED);
            }
        }
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if(enableNotice(gatt))
                {
                    setConnected(true);
                    broadcastUpdate(ACTION_BLE_CONNECTED);
                }else {
                    closeDevice();
                    setConnected(false);
                    broadcastUpdate(ACTION_BLE_DISCONNECTED);
                }
            }
        }

        /**
         * 收到通知
         * @param gatt
         * @param characteristic
         */
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            byte[] data =new byte[8];
            System.arraycopy(characteristic.getValue(), 0, data, 0, 8);
            if (!Agreement.dataCheck(data))return;//校验失败
            dataCallBack.onCallBack(data);
        }
    };

    /**
     * 写入数据，通知模式读取
     * @param bytes
     */

    public  static boolean writeDataBLE(byte [] bytes)
    {
        mCharacteristic.setValue(bytes);
        boolean isSucc = mBluetoothGatt.writeCharacteristic(mCharacteristic);
        return isSucc;
    }

    private static void broadcastUpdate(final String action) {
        final Intent intent = new Intent(action);
        App.mContext.sendBroadcast(intent);
    }

    /**
     * 开启通知功能
     * @param gatt
     */
    private static boolean enableNotice(BluetoothGatt gatt)
    {
        //获取BluetoothSocket，UUID需要和蓝牙服务端保持一致,服务UUID
        mBluetoothGattService = gatt.getService(UUID.fromString(serviceUUID));
        if (mBluetoothGattService==null)return false;
        mCharacteristic=mBluetoothGattService.getCharacteristic(UUID.fromString(characteristicUUID));
        boolean succ= mBluetoothGatt.setCharacteristicNotification(mCharacteristic, true);
        if (!succ)return false;
        BluetoothGattDescriptor dsc  =mCharacteristic.getDescriptor(UUID.fromString(descriptorUUID));
        dsc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
       return mBluetoothGatt.writeDescriptor(dsc);
    }

    public abstract static class CharacteristicCallBack
    {
       public abstract void onCallBack(byte[] data);
    }
}
